package jp.sourceforge.akjrcp.text_douga.item;

import java.awt.AlphaComposite;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;

import jp.sourceforge.akjrcp.draw.DecoratedShapePainter;
import jp.sourceforge.akjrcp.text_douga.DougaPreference;
import jp.sourceforge.akjrcp.text_douga.DougaSystem;
import jp.sourceforge.akjrcp.text_douga.ImageObject;

/*
 * normal image
 */
public class TextItem extends AbstractItem{
	
	
	private String text;
	
	
	private Font font=new Font(DEFAULT_FONT_NAME,DEFAULT_FONT_STYLE,DEFAULT_FONT_SIZE);
	
	//private static BufferedImage tmpBuffer=new BufferedImage(1,1,BufferedImage.TYPE_BYTE_GRAY);
	//private static Graphics2D tmpG2=(Graphics2D) tmpBuffer.getGraphics();

	
	private Shape[] textShapes;
	

	private DecoratedShapePainter decoratedShapePainter=new DecoratedShapePainter();
	
	//TODO FONT
	public static final String DEFAULT_FONT_NAME="MS Mincho";
	public static final int DEFAULT_FONT_SIZE=18;
	public static final int DEFAULT_FONT_STYLE=Font.PLAIN;
	
	private int text_align=TextItem.LEFT;//TODO can set;
	private int text_margin=6;//TODO can set;
	public TextItem(String text){
		this.text=text;
		setAlign(CENTER);
		setValign(BOTTOM);
		setFadeInTime(0);
		setFadeOutTime(0.3);
	}
	
	public String toString(){
		return "TextItem:"+super.toString()+" text="+text+" font="+font;
	}
	
	public TextItem(){
		this("");
	}
	public boolean writeFrame(DougaPreference preference,ImageObject baseImage,int frame)throws IOException{
		boolean written=false;
		if(duration==DougaSystem.FOREEVER){//maybe this is background image
			written=true;
		}
		double frameTime=(double)(frame-1)/preference.getFps();//to change start 0
		if(written==false){
		
		if(frameTime>=startTime && frameTime<startTime+duration){
			log.info("intime:"+frameTime+" start="+startTime+" end="+(startTime+duration));
			written=true;
			}
		}
		
		if(written==true){
			//TODO wrap text. use LineTextData.class or wrapString()
			//Rectangle stringRect=getStringShape(baseImage.getImage()).getBounds();
			Graphics2D g2=(Graphics2D) baseImage.getImage().getGraphics();
			g2.setFont(font);
			//drawing;
			Rectangle drawRect=getDrawRect(preference,baseImage.getImage());
			//g2.drawRect(drawRect.x, drawRect.y, drawRect.width, drawRect.height);//debug
			
			
			log.trace("drawrect:"+drawRect);
			
			
			
			//ALPAH
			float tp=getFrameTransparent(frameTime);
			g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tp));//use tp!
			log.trace(font);
			
			int dx=drawRect.x;
			int dy=drawRect.y+drawRect.height-(textShapes.length)*font.getSize()-(textShapes.length-1)*text_margin+font.getSize();
			g2.translate(dx,dy);//for font.
			for (int i = 0; i < textShapes.length; i++) {
				//text align left
				log.info("i="+i+" dx="+dx+" dy="+dy);
				decoratedShapePainter.paint(g2, textShapes[i]);
				g2.translate(0, font.getSize()+text_margin);
			}
			
			//int dx=(drawRect.width-getStringShape(baseImage.getImage()).getBounds().width)/2+drawRect.x-stringRect.x;
			//int dy=(drawRect.height-font.getSize())/2+drawRect.y-stringRect.y;//shape
			
			
			
		}
		
		return written;
	}
	private int getDrawTextWidth(DougaPreference preference){
		int w=getWidth();
		if(w==0){
			w=preference.getWidth();
			}
		return w;
	}
	public Shape[] getStringShape(BufferedImage dstImage,DougaPreference preference){
		if(textShapes!=null){
			return textShapes;
		}
		int w=getDrawTextWidth(preference);
		textShapes=makeStringShapes(text,font,dstImage,w);
		return textShapes;
	}
	/*
	 * old and english only
	 */
	/*
	public String[] wrapString(FontMetrics metrics,int maxwidth,String str){
		List<String> arrayList=new ArrayList<String>();
		String dummy_ret="__DUMMY_RETURN__";
		String value=StringUtils.replace(str,"\r\n","\n");
        value=StringUtils.replace(value,"\r","\n");
        value=StringUtils.replace(value, "\\\\n", dummy_ret);
		value=StringUtils.replace(value,"\\n","\n");
		String lines[]=str.split("\n");//split by line
		String newLine="";
		for(int i=0;i<lines.length;i++){
			lines[i]=StringUtils.replace(str,dummy_ret,"\\\\n");//back dummy \n for print
			  String words[]=lines[i].split(" ");
			            String tmpLine="";
			               for(int k=0;k<words.length;k++){
			                   tmpLine+=words[k];
			                   if(metrics.stringWidth(tmpLine)>maxwidth){
			                   if(newLine.length()>0){
			                	   arrayList.add(newLine);
				                    newLine="";
				                    tmpLine=words[k];
			                   		}else{
			                   		 for(int j=0;j<words[k].length();j++){
			                   		     tmpLine+=words[k].charAt(j);
			           	               if(metrics.stringWidth(newLine)>maxwidth){
			           	            	arrayList.add(tmpLine);
			           	                   tmpLine="";
			           	                   newLine="";
			           	               }else{
			           	                   newLine=tmpLine;
			           	               }
			           	           }
			                   		}
			                   }else{
			                       tmpLine=tmpLine+" ";
			                       newLine=tmpLine;
			                   }
			               }
			               
			           
			           if(tmpLine.length()>0){
			        	   arrayList.add(tmpLine);
			               
			           }
			           newLine="";
			        }
	return arrayList.toArray(new String[arrayList.size()]);
	}
	*/
	
	public static Shape makeStringShape(String text,Font font,BufferedImage dstImage){
		
	Graphics2D g2 = (Graphics2D)dstImage.getGraphics();
	TextLayout textLayout =
	  new TextLayout(text, font, g2.getFontRenderContext());
	Shape shape = textLayout.getOutline(new AffineTransform());
	g2.dispose();
	return shape;
	}
	
	public static Shape[] makeStringShapes(String text,Font font,BufferedImage dstImage,int maxwidth){
		String lines[]=TextUtils.wrapText(text, font, maxwidth);
		Shape[] shapes=new Shape[lines.length];
		for (int i = 0; i < shapes.length; i++) {
			shapes[i]=makeStringShape(lines[i],font,dstImage);
		}
		return shapes;
	}
	
	public Rectangle getStringRect(BufferedImage dstImage,DougaPreference preference){
		Rectangle rect=new Rectangle();
		Shape[] shapes=getStringShape(dstImage,preference);//preload
		rect.height=shapes.length*font.getSize()+(shapes.length-1)*text_margin;
		
		for (int i = 0; i < shapes.length; i++) {
			rect.width=Math.max(rect.width, shapes[i].getBounds().width);
		}
		return rect;
	}
	

	
	public Rectangle getDrawRect(DougaPreference preference,BufferedImage baseImage){
		if(text==null || text.length()==0){
			log.warn("no text");
			return null;
		}
		
		//Rectangle2D textRect=g2.getFontMetrics().getStringBounds(text, g2);//what?
		Rectangle textRect=getStringRect(baseImage,preference);
		
		int textwidth=textRect.width;
		int textheight=textRect.height;
		log.trace("text:"+textwidth+","+textheight);
		//Rectangle textRect=tmpG2.getFontMetrics(font).getStringBounds(text, context)
		int dw=width;
		int dh=height;
		if(dw==0){
			dw=textwidth;
		}
		if(dh==0){
			dh=textheight;
		}
		int dx=0;
		if(align==NONE){
			dx=x;
		}else{
			if(align==LEFT){
				dx=marginLeft;
			}else if(align==RIGHT){
				dx=preference.getWidth()-dw-marginRight;
			}else if(align==CENTER){
				dx=marginRight+(preference.getWidth()-marginLeft-marginRight-dw)/2;
			}else{
				log.warn("invalid align:"+align);
			}
		}
		int dy=0;
		if(valign==NONE){
			dy=y;
		}else{
			if(valign==TOP){
				dy=marginTop;
			}else if(valign==BOTTOM){
				dy=preference.getHeight()-dh-marginBottom;
			}else if(valign==MIDDLE){
				dy=(preference.getHeight()-dh-marginTop-marginBottom)/2;
			}else{
				log.warn("invalid valign:"+valign);
			}
		}
		return new Rectangle(dx,dy,dw,dh);
	}

	public Font getFont() {
		return font;
	}


	public void setFont(Font font) {
		this.font = font;
	}


	public String getText() {
		return text;
	}


	public void setText(String text) {
		this.text = text;
	}

	public DecoratedShapePainter getDecoratedShapePainter() {
		return decoratedShapePainter;
	}

	public void setDecoratedShapePainter(DecoratedShapePainter decoratedShapePainter) {
		this.decoratedShapePainter = decoratedShapePainter;
	}





}
